//@author A0117173L
package ui;

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;

import java.awt.Font;

import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import javax.swing.UIManager;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import logic.DisplayTaskInfo;
import logic.DisplayTaskInfoList;
import logic.Logic;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import java.awt.Color;

import javax.swing.JTabbedPane;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * 
 *         All of the UI part is written by Liang Ye (A0117173L).
 * 
 */

public class Main extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel contentPane;
	private JTextField inputTextField;

	public Logic logic;
	public DisplayTaskInfo displayTaskInfo;

	private static final String COMMAND_GUIDANCE = "command: add / edit / remove / display / complete / pending / undo / redo / exit";
	private static final String ADD_GUIDANCE = "add [description] [date] [time]  *(you can omit date or time)*";
	private static final String REMOVE_GUIDANCE = "remove [task id] / [query] / [list]     ie. [list] : pending, complete, all";
	private static final String EDIT_GUIDANCE = "edit [task id] [field type] [changes]     ie. edit 1 end time 4pm";
	private static final String DISPLAY_GUIDANCE = "display [query]     ie. display meeting";
	private static final String COMPLETE_GUIDANCE = "complete [list] / [task id]     ie. [list] : pending, all";
	private static final String PENDING_GUIDANCE = "pending [list] / [task id]     ie. [list] : complete, all";
	private static final String UNDO_GUIDANCE = "*multiple undos allowed";
	private static final String REDO_GUIDANCE = "*must use with undo";
	private static final String EXIT_GUIDANCE = "Are you sure?";
	private static final String ERROR_IN_GETKEYCODE = "error in getKeyCode!";
	private final int ONE_SECOND = 1000; // update every second

	private static String inputString = ""; // the string user input

	private boolean isSmall = false; // To show if the window become small
	private Thread timeThread;
	private Thread taskThread;
	private Calendar calendar = null;

	private JTable outputTable_All;
	private JTable outputTable_Search;
	private JTable outputTable_Urgent;

	private DisplayTaskInfoList displayAllTasksInfoList = null;
	private DisplayTaskInfoList displaySearchTasksInfoList = null;
	private DisplayTaskInfoList displayUrgentTasksInfoList = null;

	private int allTaskRowNumber = -1; // To record the row number of all task
										// display table
	private int searchTaskRowNumber = -1; // To record the row number of search
											// task display table
	private int urgentTaskRowNumber = -1; // To record the row number of urgent
											// task display table
	// These is to control which tab is showing to user
	private boolean isAll = false;
	private boolean isSearch = false;
	private boolean isUrgent = true;

	private int numberOfPendingTasks;
	private int numberOfCompleteTasks;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 * 
	 * @throws Exception
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws ClassNotFoundException
	 */
	public Main() throws ClassNotFoundException, InstantiationException,
			IllegalAccessException, Exception {

		setIconImage(Toolkit.getDefaultToolkit().getImage(
				Main.class.getResource("/icon.png")));
		UIManager
				.setLookAndFeel("com.jtattoo.plaf.aluminium.AluminiumLookAndFeel");
		logic = new Logic();
		setTitle("TASKey");

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 946, 580);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);

		final JLabel guidanceLabel = new JLabel();
		guidanceLabel.setForeground(new Color(128, 0, 128));
		guidanceLabel.setFont(new Font("Eras Medium ITC", Font.PLAIN, 15));
		guidanceLabel.setBounds(10, 149, 920, 21);
		contentPane.add(guidanceLabel);
		guidanceLabel.setText(COMMAND_GUIDANCE);

		final JLabel taskLabel = new JLabel("");
		taskLabel.setFont(new Font("SimSun-ExtB", Font.BOLD, 17));
		taskLabel.setBounds(10, 516, 557, 15);
		contentPane.add(taskLabel);

		final JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
		tabbedPane.setBounds(10, 180, 910, 326);
		contentPane.add(tabbedPane);

		final JScrollPane scrollPane_All = new JScrollPane();
		tabbedPane.addTab("All", null, scrollPane_All, null);
		outputTable_All = new JTable();

		outputTable_All.setColumnSelectionAllowed(true);
		outputTable_All.setCellSelectionEnabled(true);
		outputTable_All.setToolTipText("");
		outputTable_All.setShowGrid(false);

		final DefaultTableModel modelAll;
		modelAll = new DefaultTableModel(new Object[][] {}, new String[] {
				"Overdue", "Status", "ID", "Description", "Start Date",
				"Start Time", "End Date", "End Time" }) {
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;
			boolean[] columnEditables = new boolean[] { false, false, false,
					false, false, false, false, false };

			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		};

		DefaultTableCellRenderer inCenterRender = new DefaultTableCellRenderer();
		DefaultTableCellRenderer statusRender = new DefaultTableCellRenderer();
		DefaultTableCellRenderer overdueRender = new DefaultTableCellRenderer();
		inCenterRender.setHorizontalAlignment(SwingConstants.CENTER);
		statusRender.setFont(new Font("Cooper Std Black", Font.BOLD, 20));
		statusRender.setForeground(Color.GREEN);
		statusRender.setHorizontalAlignment(SwingConstants.CENTER);
		overdueRender.setFont(new Font("Cooper Std Black", Font.BOLD, 20));
		overdueRender.setForeground(Color.RED);
		overdueRender.setHorizontalAlignment(SwingConstants.CENTER);
		outputTable_All.setModel(modelAll);
		outputTable_All.getColumnModel().getColumn(0).setPreferredWidth(1);
		outputTable_All.getColumnModel().getColumn(1).setPreferredWidth(1);
		outputTable_All.getColumnModel().getColumn(2).setPreferredWidth(1);
		outputTable_All.getColumnModel().getColumn(3).setPreferredWidth(320);
		outputTable_All.getColumnModel().getColumn(5).setPreferredWidth(36);
		outputTable_All.getColumnModel().getColumn(7).setPreferredWidth(36);
		outputTable_All.getColumn("Overdue").setCellRenderer(overdueRender);
		outputTable_All.getColumn("ID").setCellRenderer(inCenterRender);
		outputTable_All.getColumn("Description")
				.setCellRenderer(inCenterRender);
		outputTable_All.getColumn("Start Date").setCellRenderer(inCenterRender);
		outputTable_All.getColumn("Start Time").setCellRenderer(inCenterRender);
		outputTable_All.getColumn("End Date").setCellRenderer(inCenterRender);
		outputTable_All.getColumn("End Time").setCellRenderer(inCenterRender);
		outputTable_All.getColumn("Status").setCellRenderer(statusRender);
		scrollPane_All.setViewportView(outputTable_All);
		outputTable_All.setRowHeight(40);
		// Initialization of allTable
		while (allTaskRowNumber >= 0) {
			modelAll.removeRow(allTaskRowNumber);
			allTaskRowNumber = allTaskRowNumber - 1;
		}

		displayAllTasksInfoList = logic.getAllTaskAttributesList();

		if (displayAllTasksInfoList != null) {
			ArrayList<DisplayTaskInfo> allTasksList = displayAllTasksInfoList
					.getTaskAttributesList(false);

			for (int i = 0; i < allTasksList.size(); i++) {
				modelAll.addRow(new Object[] {});
				allTaskRowNumber = allTaskRowNumber + 1;
				if (allTasksList.get(i).getOverDueStatus()
						.equals("Not over due")) {
					outputTable_All.setValueAt(" ", i, 0);
				} else {
					outputTable_All.setValueAt("Y", i, 0);
				}
				if (allTasksList.get(i).getStatus().equals("Pending")) {
					outputTable_All.setValueAt(" ", i, 1);
				} else {
					outputTable_All.setValueAt("Y", i, 1);
				}
				outputTable_All.setValueAt(((i + 1) + ""), i, 2);
				outputTable_All.setValueAt(
						allTasksList.get(i).getDescription(), i, 3);
				outputTable_All.setValueAt(allTasksList.get(i).getStartDate(),
						i, 4);
				outputTable_All.setValueAt(allTasksList.get(i).getStartTime(),
						i, 5);
				outputTable_All.setValueAt(allTasksList.get(i).getEndDate(), i,
						6);
				outputTable_All.setValueAt(allTasksList.get(i).getEndTime(), i,
						7);
			}
		}

		// This is to change the color of clashing tasks
		if (displayAllTasksInfoList != null) {
			final ArrayList<Integer> clashingTasksIndexList = logic
					.getClashingTasksIndexList();
			DefaultTableCellRenderer colorTableCellRenderer_All = new DefaultTableCellRenderer() {

				private static final long serialVersionUID = 1L;

				public Component getTableCellRendererComponent(JTable table,
						Object value, boolean isSelected, boolean hasFocus,
						int row, int column) {

					if (clashingTasksIndexList.contains(row)) {
						setBackground(Color.red);
					} else {
						setBackground(null);
					}

					return super.getTableCellRendererComponent(table, value,
							isSelected, hasFocus, row, column);

				}
			};
			colorTableCellRenderer_All
					.setHorizontalAlignment(SwingConstants.CENTER);
			outputTable_All.getColumn("Description").setCellRenderer(
					colorTableCellRenderer_All);
		}

		numberOfPendingTasks = displayAllTasksInfoList
				.getNumberOfPendingTasks();
		numberOfCompleteTasks = displayAllTasksInfoList
				.getNumberOfCompleteTasks();
		taskLabel.setText("Pending: " + numberOfPendingTasks + "   "
				+ "Complete: " + numberOfCompleteTasks + "   " + "Total: "
				+ (numberOfPendingTasks + numberOfCompleteTasks));

		final JScrollPane scrollPane_Search = new JScrollPane();
		tabbedPane.addTab("Search", null, scrollPane_Search, null);

		final DefaultTableModel modelSearch;
		modelSearch = new DefaultTableModel(new Object[][] {}, new String[] {
				"Overdue", "Status", "ID", "Description", "Start Date",
				"Start Time", "End Date", "End Time" }) {
			/**
				 * 
				 */
			private static final long serialVersionUID = 1L;
			boolean[] columnEditables = new boolean[] { false, false, false,
					false, false, false, false, false };

			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		};

		outputTable_Search = new JTable();
		outputTable_Search.setToolTipText("");
		outputTable_Search.setRowHeight(40);
		outputTable_Search.setColumnSelectionAllowed(true);
		outputTable_Search.setCellSelectionEnabled(true);
		scrollPane_Search.setViewportView(outputTable_Search);
		outputTable_Search.setModel(modelSearch);
		outputTable_Search.getColumnModel().getColumn(0).setPreferredWidth(1);
		outputTable_Search.getColumnModel().getColumn(1).setPreferredWidth(1);
		outputTable_Search.getColumnModel().getColumn(2).setPreferredWidth(1);
		outputTable_Search.getColumnModel().getColumn(3).setPreferredWidth(320);
		outputTable_Search.getColumnModel().getColumn(5).setPreferredWidth(36);
		outputTable_Search.getColumnModel().getColumn(7).setPreferredWidth(36);
		outputTable_Search.getColumn("Overdue").setCellRenderer(overdueRender);
		outputTable_Search.getColumn("ID").setCellRenderer(inCenterRender);
		outputTable_Search.getColumn("Description").setCellRenderer(
				inCenterRender);
		outputTable_Search.getColumn("Start Date").setCellRenderer(
				inCenterRender);
		outputTable_Search.getColumn("Start Time").setCellRenderer(
				inCenterRender);
		outputTable_Search.getColumn("End Date")
				.setCellRenderer(inCenterRender);
		outputTable_Search.getColumn("End Time")
				.setCellRenderer(inCenterRender);
		outputTable_Search.getColumn("Status").setCellRenderer(statusRender);
		outputTable_Search.setShowGrid(false);

		final JScrollPane scrollPane_Urgent = new JScrollPane();
		tabbedPane.addTab("Urgent", null, scrollPane_Urgent, null);

		final DefaultTableModel modelUrgent;
		modelUrgent = new DefaultTableModel(new Object[][] {}, new String[] {
				"Overdue", "Status", "ID", "Description", "Start Date",
				"Start Time", "End Date", "End Time" }) {
			/**
				 * 
				 */
			private static final long serialVersionUID = 1L;
			boolean[] columnEditables = new boolean[] { false, false, false,
					false, false, false, false, false };

			public boolean isCellEditable(int row, int column) {
				return columnEditables[column];
			}
		};

		outputTable_Urgent = new JTable();
		outputTable_Urgent.setToolTipText("");
		outputTable_Urgent.setRowHeight(40);
		outputTable_Urgent.setColumnSelectionAllowed(true);
		outputTable_Urgent.setCellSelectionEnabled(true);
		scrollPane_Urgent.setViewportView(outputTable_Urgent);
		outputTable_Urgent.setModel(modelUrgent);
		outputTable_Urgent.getColumnModel().getColumn(0).setPreferredWidth(1);
		outputTable_Urgent.getColumnModel().getColumn(1).setPreferredWidth(1);
		outputTable_Urgent.getColumnModel().getColumn(2).setPreferredWidth(1);
		outputTable_Urgent.getColumnModel().getColumn(3).setPreferredWidth(320);
		outputTable_Urgent.getColumnModel().getColumn(5).setPreferredWidth(36);
		outputTable_Urgent.getColumnModel().getColumn(7).setPreferredWidth(36);
		outputTable_Urgent.getColumn("Overdue").setCellRenderer(overdueRender);
		outputTable_Urgent.getColumn("ID").setCellRenderer(inCenterRender);
		outputTable_Urgent.getColumn("Description").setCellRenderer(
				inCenterRender);
		outputTable_Urgent.getColumn("Start Date").setCellRenderer(
				inCenterRender);
		outputTable_Urgent.getColumn("Start Time").setCellRenderer(
				inCenterRender);
		outputTable_Urgent.getColumn("End Date")
				.setCellRenderer(inCenterRender);
		outputTable_Urgent.getColumn("End Time")
				.setCellRenderer(inCenterRender);
		outputTable_Urgent.getColumn("Status").setCellRenderer(statusRender);
		outputTable_Urgent.setShowGrid(false);
		// Initialization of urgentTable
		while (urgentTaskRowNumber >= 0) {
			modelUrgent.removeRow(urgentTaskRowNumber);
			urgentTaskRowNumber = urgentTaskRowNumber - 1;
		}

		displayUrgentTasksInfoList = logic.getUrgentTaskAttributesList();

		if (displayUrgentTasksInfoList != null) {
			ArrayList<DisplayTaskInfo> urgentTasksList = displayUrgentTasksInfoList
					.getTaskAttributesList(true);

			for (int i = 0; i < urgentTasksList.size(); i++) {
				modelUrgent.addRow(new Object[] {});
				urgentTaskRowNumber = urgentTaskRowNumber + 1;
				if (urgentTasksList.get(i).getOverDueStatus()
						.equals("Not over due")) {
					outputTable_Urgent.setValueAt(" ", i, 0);
				} else {
					outputTable_Urgent.setValueAt("Y", i, 0);
				}
				if (urgentTasksList.get(i).getStatus().equals("Pending")) {
					outputTable_Urgent.setValueAt(" ", i, 1);
				} else {
					outputTable_Urgent.setValueAt("Y", i, 1);
				}
				outputTable_Urgent.setValueAt(
						urgentTasksList.get(i).getIndex() + 1, i, 2);
				outputTable_Urgent.setValueAt(urgentTasksList.get(i)
						.getDescription(), i, 3);
				outputTable_Urgent.setValueAt(urgentTasksList.get(i)
						.getStartDate(), i, 4);
				outputTable_Urgent.setValueAt(urgentTasksList.get(i)
						.getStartTime(), i, 5);
				outputTable_Urgent.setValueAt(urgentTasksList.get(i)
						.getEndDate(), i, 6);
				outputTable_Urgent.setValueAt(urgentTasksList.get(i)
						.getEndTime(), i, 7);
			}
		}
		tabbedPane.setSelectedComponent(scrollPane_Urgent);

		JLabel nameLabel = new JLabel("TASKey");
		nameLabel.setFont(new Font("Freestyle Script", Font.BOLD, 50));
		nameLabel.setBounds(417, 10, 136, 82);
		contentPane.add(nameLabel);

		inputTextField = new JTextField();
		inputTextField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				int keyCode = 0;
				try {
					keyCode = e.getKeyCode();
				} catch (Exception e1) {
					System.err.println(ERROR_IN_GETKEYCODE);
				}
				if (keyCode == KeyEvent.VK_CONTROL) {
					if (isSmall) {
						setBounds(100, 100, 946, 580);
						isSmall = false;
					} else {
						setBounds(100, 100, 946, 220);
						isSmall = true;
					}
				} else if (keyCode == KeyEvent.VK_BACK_SPACE) {
					if (!(inputString.equals(""))) {
						inputString = inputString.substring(0,
								inputString.length() - 1);
					}
				} else if (keyCode == KeyEvent.VK_SHIFT) {
					// Use up or down to change the showing tab
				} else if (keyCode == KeyEvent.VK_UP) {
					if (isAll) {
						tabbedPane.setSelectedComponent(scrollPane_Urgent);
						isAll = false;
						isSearch = false;
						isUrgent = true;
						if (displayUrgentTasksInfoList != null) {
							numberOfPendingTasks = displayUrgentTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displayUrgentTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					} else if (isSearch) {
						tabbedPane.setSelectedComponent(scrollPane_All);
						isAll = true;
						isSearch = false;
						isUrgent = false;
						if (displayAllTasksInfoList != null) {
							numberOfPendingTasks = displayAllTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displayAllTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					} else if (isUrgent) {
						tabbedPane.setSelectedComponent(scrollPane_Search);
						isAll = false;
						isSearch = true;
						isUrgent = false;
						if (displaySearchTasksInfoList != null) {
							numberOfPendingTasks = displaySearchTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displaySearchTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					}
				} else if (keyCode == KeyEvent.VK_DOWN) {
					if (isAll) {
						tabbedPane.setSelectedComponent(scrollPane_Search);
						isAll = false;
						isSearch = true;
						isUrgent = false;
						if (displaySearchTasksInfoList != null) {
							numberOfPendingTasks = displaySearchTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displaySearchTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					} else if (isSearch) {
						tabbedPane.setSelectedComponent(scrollPane_Urgent);
						isAll = false;
						isSearch = false;
						isUrgent = true;
						if (displayUrgentTasksInfoList != null) {
							numberOfPendingTasks = displayUrgentTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displayUrgentTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					} else if (isUrgent) {
						tabbedPane.setSelectedComponent(scrollPane_All);
						isAll = true;
						isSearch = false;
						isUrgent = false;
						if (displayAllTasksInfoList != null) {
							numberOfPendingTasks = displayAllTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displayAllTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					}

				} else {
					inputString = inputString + (char) (keyCode + 32);
				}
				if (inputString.equals("")) {
					guidanceLabel.setText(COMMAND_GUIDANCE);
				}
				guidanceLabel.setText(guidanceDisplay(inputString));
				if (keyCode == KeyEvent.VK_ENTER) {

					guidanceLabel.setText(logic.executeCommand(inputTextField
							.getText()));
					inputTextField.setText("");
					inputString = "";
					// Get tasks and refresh tables.
					while (allTaskRowNumber >= 0) {
						modelAll.removeRow(allTaskRowNumber);
						allTaskRowNumber = allTaskRowNumber - 1;
					}

					while (searchTaskRowNumber >= 0) {
						modelSearch.removeRow(searchTaskRowNumber);
						searchTaskRowNumber = searchTaskRowNumber - 1;
					}

					while (urgentTaskRowNumber >= 0) {
						modelUrgent.removeRow(urgentTaskRowNumber);
						urgentTaskRowNumber = urgentTaskRowNumber - 1;
					}

					displayAllTasksInfoList = logic.getAllTaskAttributesList();

					displaySearchTasksInfoList = logic
							.getSearchTaskAttributesList();

					displayUrgentTasksInfoList = logic
							.getUrgentTaskAttributesList();

					if (displayAllTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> allTasksList = displayAllTasksInfoList
								.getTaskAttributesList(false);

						for (int i = 0; i < allTasksList.size(); i++) {
							modelAll.addRow(new Object[] {});
							allTaskRowNumber = allTaskRowNumber + 1;
							;
							if (allTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_All.setValueAt(" ", i, 0);
							} else {
								outputTable_All.setValueAt("Y", i, 0);
							}
							if (allTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_All.setValueAt(" ", i, 1);
							} else {
								outputTable_All.setValueAt("Y", i, 1);
							}
							outputTable_All.setValueAt(((i + 1) + ""), i, 2);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getDescription(), i, 3);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getStartDate(), i, 4);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getStartTime(), i, 5);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getEndDate(), i, 6);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getEndTime(), i, 7);
						}
					}

					if (displayAllTasksInfoList != null) {
						final ArrayList<Integer> clashingTasksIndexList = logic
								.getClashingTasksIndexList();
						DefaultTableCellRenderer colorTableCellRenderer_All = new DefaultTableCellRenderer() {

							private static final long serialVersionUID = 1L;

							public Component getTableCellRendererComponent(
									JTable table, Object value,
									boolean isSelected, boolean hasFocus,
									int row, int column) {

								if (clashingTasksIndexList.contains(row)) {
									setBackground(Color.red);
								} else {
									setBackground(null);
								}

								return super.getTableCellRendererComponent(
										table, value, isSelected, hasFocus,
										row, column);

							}
						};
						colorTableCellRenderer_All
								.setHorizontalAlignment(SwingConstants.CENTER);
						outputTable_All.getColumn("Description")
								.setCellRenderer(colorTableCellRenderer_All);
					}

					if (displaySearchTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> searchTasksList = displaySearchTasksInfoList
								.getTaskAttributesList(true);

						for (int i = 0; i < searchTasksList.size(); i++) {
							modelSearch.addRow(new Object[] {});
							searchTaskRowNumber = searchTaskRowNumber + 1;
							if (searchTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_Search.setValueAt(" ", i, 0);
							} else {
								outputTable_Search.setValueAt("Y", i, 0);
							}
							if (searchTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_Search.setValueAt(" ", i, 1);
							} else {
								outputTable_Search.setValueAt("Y", i, 1);
							}
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getIndex() + 1, i, 2);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getDescription(), i, 3);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getStartDate(), i, 4);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getStartTime(), i, 5);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getEndDate(), i, 6);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getEndTime(), i, 7);
						}
					}

					if (displayUrgentTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> urgentTasksList = displayUrgentTasksInfoList
								.getTaskAttributesList(true);

						for (int i = 0; i < urgentTasksList.size(); i++) {
							modelUrgent.addRow(new Object[] {});
							urgentTaskRowNumber = urgentTaskRowNumber + 1;
							if (urgentTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_Urgent.setValueAt(" ", i, 0);
							} else {
								outputTable_Urgent.setValueAt("Y", i, 0);
							}
							if (urgentTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_Urgent.setValueAt(" ", i, 1);
							} else {
								outputTable_Urgent.setValueAt("Y", i, 1);
							}
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getIndex() + 1, i, 2);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getDescription(), i, 3);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getStartDate(), i, 4);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getStartTime(), i, 5);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getEndDate(), i, 6);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getEndTime(), i, 7);
						}
					}
					// If the command is search, UI will show search tab.
					if (logic.isSearchTabOn()) {
						tabbedPane.setSelectedComponent(scrollPane_Search);
						isAll = false;
						isSearch = true;
						isUrgent = false;
						if (displaySearchTasksInfoList != null) {
							numberOfPendingTasks = displaySearchTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displaySearchTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					} else {
						tabbedPane.setSelectedComponent(scrollPane_All);
						isAll = true;
						isSearch = false;
						isUrgent = false;
						if (displayAllTasksInfoList != null) {
							numberOfPendingTasks = displayAllTasksInfoList
									.getNumberOfPendingTasks();
							numberOfCompleteTasks = displayAllTasksInfoList
									.getNumberOfCompleteTasks();
						} else {
							numberOfPendingTasks = 0;
							numberOfCompleteTasks = 0;
						}
						taskLabel
								.setText("Pending: "
										+ numberOfPendingTasks
										+ "   "
										+ "Complete: "
										+ numberOfCompleteTasks
										+ "   "
										+ "Total: "
										+ (numberOfPendingTasks + numberOfCompleteTasks));
					}

				}
			}

			/**
			 * For automatically finishing command
			 */
			@Override
			public void keyReleased(KeyEvent e) {
				int keyCode = 0;
				try {
					keyCode = e.getKeyCode();
				} catch (Exception e1) {
					System.err.println(ERROR_IN_GETKEYCODE);
				}

				if ((keyCode != KeyEvent.VK_BACK_SPACE)
						&& (keyCode != KeyEvent.VK_ENTER)) {
					if (inputString.equals("a")) {
						inputTextField.setText("add ");
						inputString = "add";
					} else if (inputString.equals("ed")) {
						inputTextField.setText("edit ");
						inputString = "edit";
					} else if (inputString.equals("rem")) {
						inputTextField.setText("remove ");
						inputString = "remove";
					} else if (inputString.equals("d")) {
						inputTextField.setText("display ");
						inputString = "display";
					} else if (inputString.equals("c")) {
						inputTextField.setText("complete ");
						inputString = "complete";
					} else if (inputString.equals("p")) {
						inputTextField.setText("pending ");
						inputString = "pending";
					} else if (inputString.equals("ex")) {
						inputTextField.setText("exit");
						inputString = "exit";
					} else if (inputString.equals("u")) {
						inputTextField.setText("undo");
						inputString = "undo";
					} else if (inputString.equals("red")) {
						inputTextField.setText("redo");
						inputString = "redo";
					}
					guidanceLabel.setText(guidanceDisplay(inputString));
				}
			}
		});
		inputTextField.setFont(new Font("Maiandra GD", Font.PLAIN, 20));
		inputTextField.setBounds(10, 99, 806, 40);
		contentPane.add(inputTextField);
		inputTextField.setColumns(10);

		JButton enterButton = new JButton("ENTER");
		enterButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				guidanceLabel.setText(logic.executeCommand(inputTextField
						.getText()));
				inputTextField.setText("");
				inputString = "";
				// Get tasks and refresh tables
				while (allTaskRowNumber >= 0) {
					modelAll.removeRow(allTaskRowNumber);
					allTaskRowNumber = allTaskRowNumber - 1;
				}

				while (searchTaskRowNumber >= 0) {
					modelSearch.removeRow(searchTaskRowNumber);
					searchTaskRowNumber = searchTaskRowNumber - 1;
				}

				while (urgentTaskRowNumber >= 0) {
					modelUrgent.removeRow(urgentTaskRowNumber);
					urgentTaskRowNumber = urgentTaskRowNumber - 1;
				}

				displayAllTasksInfoList = logic.getAllTaskAttributesList();

				displaySearchTasksInfoList = logic
						.getSearchTaskAttributesList();

				displayUrgentTasksInfoList = logic
						.getUrgentTaskAttributesList();

				if (displayAllTasksInfoList != null) {
					ArrayList<DisplayTaskInfo> allTasksList = displayAllTasksInfoList
							.getTaskAttributesList(false);

					for (int i = 0; i < allTasksList.size(); i++) {
						modelAll.addRow(new Object[] {});
						allTaskRowNumber = allTaskRowNumber + 1;
						if (allTasksList.get(i).getOverDueStatus()
								.equals("Not over due")) {
							outputTable_All.setValueAt(" ", i, 0);
						} else {
							outputTable_All.setValueAt("Y", i, 0);
						}
						if (allTasksList.get(i).getStatus().equals("Pending")) {
							outputTable_All.setValueAt(" ", i, 1);
						} else {
							outputTable_All.setValueAt("Y", i, 1);
						}
						outputTable_All.setValueAt(((i + 1) + ""), i, 2);
						outputTable_All.setValueAt(allTasksList.get(i)
								.getDescription(), i, 3);
						outputTable_All.setValueAt(allTasksList.get(i)
								.getStartDate(), i, 4);
						outputTable_All.setValueAt(allTasksList.get(i)
								.getStartTime(), i, 5);
						outputTable_All.setValueAt(allTasksList.get(i)
								.getEndDate(), i, 6);
						outputTable_All.setValueAt(allTasksList.get(i)
								.getEndTime(), i, 7);
					}
				}

				if (displayAllTasksInfoList != null) {
					final ArrayList<Integer> clashingTasksIndexList = logic
							.getClashingTasksIndexList();
					DefaultTableCellRenderer colorTableCellRenderer_All = new DefaultTableCellRenderer() {

						private static final long serialVersionUID = 1L;

						public Component getTableCellRendererComponent(
								JTable table, Object value, boolean isSelected,
								boolean hasFocus, int row, int column) {

							if (clashingTasksIndexList.contains(row)) {
								setBackground(Color.red);
							} else {
								setBackground(null);
							}

							return super.getTableCellRendererComponent(table,
									value, isSelected, hasFocus, row, column);

						}
					};
					colorTableCellRenderer_All
							.setHorizontalAlignment(SwingConstants.CENTER);
					outputTable_All.getColumn("Description").setCellRenderer(
							colorTableCellRenderer_All);
				}

				if (displaySearchTasksInfoList != null) {
					ArrayList<DisplayTaskInfo> searchTasksList = displaySearchTasksInfoList
							.getTaskAttributesList(true);

					for (int i = 0; i < searchTasksList.size(); i++) {
						modelSearch.addRow(new Object[] {});
						searchTaskRowNumber = searchTaskRowNumber + 1;
						if (searchTasksList.get(i).getOverDueStatus()
								.equals("Not over due")) {
							outputTable_Search.setValueAt(" ", i, 0);
						} else {
							outputTable_Search.setValueAt("Y", i, 0);
						}
						if (searchTasksList.get(i).getStatus()
								.equals("Pending")) {
							outputTable_Search.setValueAt(" ", i, 1);
						} else {
							outputTable_Search.setValueAt("Y", i, 1);
						}
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getIndex() + 1, i, 2);
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getDescription(), i, 3);
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getStartDate(), i, 4);
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getStartTime(), i, 5);
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getEndDate(), i, 6);
						outputTable_Search.setValueAt(searchTasksList.get(i)
								.getEndTime(), i, 7);
					}
				}

				if (displayUrgentTasksInfoList != null) {
					ArrayList<DisplayTaskInfo> urgentTasksList = displayUrgentTasksInfoList
							.getTaskAttributesList(true);

					for (int i = 0; i < urgentTasksList.size(); i++) {
						modelUrgent.addRow(new Object[] {});
						urgentTaskRowNumber = urgentTaskRowNumber + 1;
						if (urgentTasksList.get(i).getOverDueStatus()
								.equals("Not over due")) {
							outputTable_Urgent.setValueAt(" ", i, 0);
						} else {
							outputTable_Urgent.setValueAt("Y", i, 0);
						}
						if (urgentTasksList.get(i).getStatus()
								.equals("Pending")) {
							outputTable_Urgent.setValueAt(" ", i, 1);
						} else {
							outputTable_Urgent.setValueAt("Y", i, 1);
						}
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getIndex() + 1, i, 2);
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getDescription(), i, 3);
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getStartDate(), i, 4);
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getStartTime(), i, 5);
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getEndDate(), i, 6);
						outputTable_Urgent.setValueAt(urgentTasksList.get(i)
								.getEndTime(), i, 7);
					}
				}
				// If the command is search, UI will show search tab.
				if (logic.isSearchTabOn()) {
					tabbedPane.setSelectedComponent(scrollPane_Search);
					isAll = false;
					isSearch = true;
					isUrgent = false;
					if (displaySearchTasksInfoList != null) {
						numberOfPendingTasks = displaySearchTasksInfoList
								.getNumberOfPendingTasks();
						numberOfCompleteTasks = displaySearchTasksInfoList
								.getNumberOfCompleteTasks();
					} else {
						numberOfPendingTasks = 0;
						numberOfCompleteTasks = 0;
					}
					taskLabel.setText("Pending: " + numberOfPendingTasks
							+ "   " + "Complete: " + numberOfCompleteTasks
							+ "   " + "Total: "
							+ (numberOfPendingTasks + numberOfCompleteTasks));
				} else {
					tabbedPane.setSelectedComponent(scrollPane_All);
					isAll = true;
					isSearch = false;
					isUrgent = false;
					if (displayAllTasksInfoList != null) {
						numberOfPendingTasks = displayAllTasksInfoList
								.getNumberOfPendingTasks();
						numberOfCompleteTasks = displayAllTasksInfoList
								.getNumberOfCompleteTasks();
					} else {
						numberOfPendingTasks = 0;
						numberOfCompleteTasks = 0;
					}
					taskLabel.setText("Pending: " + numberOfPendingTasks
							+ "   " + "Complete: " + numberOfCompleteTasks
							+ "   " + "Total: "
							+ (numberOfPendingTasks + numberOfCompleteTasks));
				}
			}
		});
		enterButton.setFont(new Font("Maiandra GD", Font.PLAIN, 15));
		enterButton.setBounds(826, 100, 94, 40);
		contentPane.add(enterButton);

		final JLabel timeLabel = new JLabel("19:19:19");
		timeLabel.setForeground(Color.BLUE);
		timeLabel.setFont(new Font("Cambria Math", Font.PLAIN, 18));
		timeLabel.setBounds(804, 10, 83, 40);
		contentPane.add(timeLabel);

		JLabel dateLabel = new JLabel("New label");
		dateLabel.setForeground(Color.BLUE);
		dateLabel.setFont(new Font("Cambria Math", Font.PLAIN, 18));
		dateLabel.setBounds(798, 43, 118, 32);
		contentPane.add(dateLabel);

		calendar = Calendar.getInstance();
		String dateString = calendar.get(Calendar.DAY_OF_MONTH) + "/"
				+ (calendar.get(Calendar.MONTH) + 1) + "/"
				+ calendar.get(Calendar.YEAR);
		dateLabel.setText(dateString);

		/**
		 * To get time every second
		 */
		timeThread = new Thread() {
			public void run() {
				while (true) {
					Date date = new Date();
					String timeString = String.format("%tT", date);
					timeLabel.setText(timeString);
					try {
						Thread.sleep(ONE_SECOND);
					} catch (Exception e) {
						System.err.println("error in timer");
					}
				}
			}
		};
		timeThread.start();

		/**
		 * To refresh tasks every 30 seconds for overdue
		 */
		taskThread = new Thread() {
			public void run() {
				while (true) {
					while (allTaskRowNumber >= 0) {
						modelAll.removeRow(allTaskRowNumber);
						allTaskRowNumber = allTaskRowNumber - 1;
					}

					while (searchTaskRowNumber >= 0) {
						modelSearch.removeRow(searchTaskRowNumber);
						searchTaskRowNumber = searchTaskRowNumber - 1;
					}

					while (urgentTaskRowNumber >= 0) {
						modelUrgent.removeRow(urgentTaskRowNumber);
						urgentTaskRowNumber = urgentTaskRowNumber - 1;
					}

					displayAllTasksInfoList = logic.getAllTaskAttributesList();

					displaySearchTasksInfoList = logic
							.getSearchTaskAttributesList();

					displayUrgentTasksInfoList = logic
							.getUrgentTaskAttributesList();

					if (displayAllTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> allTasksList = displayAllTasksInfoList
								.getTaskAttributesList(false);

						for (int i = 0; i < allTasksList.size(); i++) {
							modelAll.addRow(new Object[] {});
							allTaskRowNumber = allTaskRowNumber + 1;
							if (allTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_All.setValueAt(" ", i, 0);
							} else {
								outputTable_All.setValueAt("Y", i, 0);
							}
							if (allTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_All.setValueAt(" ", i, 1);
							} else {
								outputTable_All.setValueAt("Y", i, 1);
							}
							outputTable_All.setValueAt(((i + 1) + ""), i, 2);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getDescription(), i, 3);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getStartDate(), i, 4);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getStartTime(), i, 5);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getEndDate(), i, 6);
							outputTable_All.setValueAt(allTasksList.get(i)
									.getEndTime(), i, 7);
						}
					}

					if (displayAllTasksInfoList != null) {
						final ArrayList<Integer> clashingTasksIndexList = logic
								.getClashingTasksIndexList();
						DefaultTableCellRenderer colorTableCellRenderer_All = new DefaultTableCellRenderer() {

							private static final long serialVersionUID = 1L;

							public Component getTableCellRendererComponent(
									JTable table, Object value,
									boolean isSelected, boolean hasFocus,
									int row, int column) {

								if (clashingTasksIndexList.contains(row)) {
									setBackground(Color.red);
								} else {
									setBackground(null);
								}

								return super.getTableCellRendererComponent(
										table, value, isSelected, hasFocus,
										row, column);

							}
						};
						colorTableCellRenderer_All
								.setHorizontalAlignment(SwingConstants.CENTER);
						outputTable_All.getColumn("Description")
								.setCellRenderer(colorTableCellRenderer_All);
					}

					if (displaySearchTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> searchTasksList = displaySearchTasksInfoList
								.getTaskAttributesList(true);

						for (int i = 0; i < searchTasksList.size(); i++) {
							modelSearch.addRow(new Object[] {});
							searchTaskRowNumber = searchTaskRowNumber + 1;
							if (searchTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_Search.setValueAt(" ", i, 0);
							} else {
								outputTable_Search.setValueAt("Y", i, 0);
							}
							if (searchTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_Search.setValueAt(" ", i, 1);
							} else {
								outputTable_Search.setValueAt("Y", i, 1);
							}
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getIndex() + 1, i, 2);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getDescription(), i, 3);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getStartDate(), i, 4);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getStartTime(), i, 5);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getEndDate(), i, 6);
							outputTable_Search.setValueAt(searchTasksList
									.get(i).getEndTime(), i, 7);
						}
					}

					if (displayUrgentTasksInfoList != null) {
						ArrayList<DisplayTaskInfo> urgentTasksList = displayUrgentTasksInfoList
								.getTaskAttributesList(true);

						for (int i = 0; i < urgentTasksList.size(); i++) {
							modelUrgent.addRow(new Object[] {});
							urgentTaskRowNumber = urgentTaskRowNumber + 1;
							if (urgentTasksList.get(i).getOverDueStatus()
									.equals("Not over due")) {
								outputTable_Urgent.setValueAt(" ", i, 0);
							} else {
								outputTable_Urgent.setValueAt("Y", i, 0);
							}
							if (urgentTasksList.get(i).getStatus()
									.equals("Pending")) {
								outputTable_Urgent.setValueAt(" ", i, 1);
							} else {
								outputTable_Urgent.setValueAt("Y", i, 1);
							}
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getIndex() + 1, i, 2);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getDescription(), i, 3);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getStartDate(), i, 4);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getStartTime(), i, 5);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getEndDate(), i, 6);
							outputTable_Urgent.setValueAt(urgentTasksList
									.get(i).getEndTime(), i, 7);
						}
					}
					try {
						Thread.sleep(29000);
					} catch (Exception e) {
						System.err.println("error in timer");
					}
				}
			}
		};
		taskThread.start();

	}

	/**
	 * 
	 * @param str
	 *            : the text user input
	 * @return the guidance that will show to user
	 */
	public static String guidanceDisplay(String str) {
		if ((str.length() >= 3)
				&& (str.substring(0, 3).toLowerCase().equals("add"))) {
			return ADD_GUIDANCE;
		} else if ((str.length() >= 4) && (str.substring(0, 4).equals("edit"))) {
			return EDIT_GUIDANCE;
		} else if ((str.length() >= 6)
				&& (str.substring(0, 6).equals("remove"))) {
			return REMOVE_GUIDANCE;
		} else if ((str.length() >= 7)
				&& (str.substring(0, 7).equals("display"))) {
			return DISPLAY_GUIDANCE;
		} else if ((str.length() >= 7)
				&& (str.substring(0, 7).equals("pending"))) {
			return PENDING_GUIDANCE;
		} else if ((str.length() >= 8)
				&& (str.substring(0, 8).equals("complete"))) {
			return COMPLETE_GUIDANCE;
		} else if ((str.length() >= 4) && (str.substring(0, 4).equals("undo"))) {
			return UNDO_GUIDANCE;
		} else if ((str.length() >= 4) && (str.substring(0, 4).equals("redo"))) {
			return REDO_GUIDANCE;
		} else if ((str.length() >= 4) && (str.substring(0, 4).equals("exit"))) {
			return EXIT_GUIDANCE;
		} else {
			return COMMAND_GUIDANCE;
		}
	}

}
